<!DOCTYPE html>
<html>

<head>
<title>Pachelbel's Canon</title>
<meta charset="UTF-8">
<script type="text/javascript" src="../../build/js/Cindy.js"></script>
<script type="text/javascript" src="../../build/js/midi-plugin.js"></script>
<script id="csinit" type="text/x-cindyscript">

use("midi");
played = false;
melody = [["fis'",1],["e'",1],["d'",1],["cis'",1],["h",1],["a",1],["h",1],["cis'",1],
  ["d'",1],["cis'",1],["h",1],["a",1],["g",1],["fis",1],["g",1],["e",1],
  ["d",1/2],["fis",1/2],["a",1/2],["g",1/2],["fis",1/2],["d",1/2],["fis",1/2],["e",1/2],
      ["d",1/2],["H",1/2],["d",1/2],["a",1/2],["g",1/2],["h",1/2],["a",1/2],["g",1/2],
  ["fis",1/2],["d",1/2],["e",1/2],["cis'",1/2],["d'",1/2],["fis'",1/2],["a'",1/2],["a",1/2],
      ["h",1/2],["g",1/2],["a",1/2],["fis",1/2],["d",1/2],["d'",1/2],["d'",3/4],["cis'",1/4],
  ["d'",1/4],["cis'",1/4],["d'",1/4],["d",1/4],["cis",1/4],["a",1/4],["e",1/4],["fis",1/4],
      ["d",1/4],["d'",1/4],["cis'",1/4],["h",1/4],["cis'",1/4],["fis'",1/4],["a'",1/4],["h'",1/4],
      ["g'",1/4],["fis'",1/4],["e'",1/4],["g'",1/4],["fis'",1/4],["e'",1/4],["d'",1/4],["cis'",1/4],
      ["h",1/4],["a",1/4],["g",1/4],["fis",1/4],["e",1/4],["g",1/4],["fis",1/4],["e",1/4],
  ["d",1/4],["e",1/4],["fis",1/4],["g",1/4],["a",1/4],["e",1/4],["a",1/4],["g",1/4],
      ["fis",1/4],["h",1/4],["a",1/4],["g",1/4],["a",1/4],["g",1/4],["fis",1/4],["e",1/4],
      ["d",1/4],["H",1/4],["h",1/4],["cis'",1/4],["d'",1/4],["cis'",1/4],["h",1/4],["a",1/4],
      ["g",1/4],["fis",1/4],["e",1/4],["h",1/4],["a",1/4],["h",1/4],["a",1/4],["g",1/4],
  ["fis",1/2],["fis'",1/2],["e'",3/2],["d'",1/2],["fis'",1],       
      ["h'",1],["a'",1],["h'",1],["cis''",1],
  ["d''",1/2],["d'",1/2],["cis'",3/2],["h",1/2],["d'",1],       
      ["d'",3/2],["d'",1/2],["d'",1/2],["g'",1/2],["e'",1/2],["a'",1/2],
  ["a'",1/4],["fis'",1/8],["g'",1/8],["a'",1/4],["fis'",1/8],["g'",1/8],["a'",1/8],
      ["a",1/8],["h",1/8],["cis'",1/8],["d'",1/8],["e'",1/8],["fis'",1/8],["g'",1/8],
      ["fis'",1/4],["d'",1/8],["e'",1/8],["fis'",1/4],
      ["fis",1/8],["g",1/8],["a",1/8],["h",1/8],["a",1/8],["g",1/8],["a",1/8],["fis",1/8],["g",1/8],["a",1/8],
   ["g",1/4],["h",1/8],["a",1/8],["g",1/4],["fis",1/8],["e",1/8],["fis",1/8],
      ["e",1/8],["d",1/8],["e",1/8],["fis",1/8],["g",1/8],["a",1/8],["h",1/8],
      ["g",1/4],["h",1/8],["a",1/8],["h",1/4],
      ["cis'",1/8],["d'",1/8],["a",1/8],["h",1/8],["cis'",1/8],["d'",1/8],["e'",1/8],["fis'",1/8],["g'",1/8],["a'",1/8],
  ["fis'",1/4],["d'",1/8],["e'",1/8],["fis'",1/4],["e'",1/8],["d'",1/8],["e'",1/8],
      ["cis'",1/8],["d'",1/8],["e'",1/8],["fis'",1/8],["e'",1/8],["d'",1/8],["cis'",1/8],
      ["d'",1/4],["h",1/8],["cis'",1/8],["d'",1/4],
      ["d",1/8],["e",1/8],["fis",1/8],["g",1/8],["fis",1/8],["e",1/8],["fis",1/8],["d'",1/8],["cis'",1/8],["d'",1/8],
  ["h",1/4],["d'",1/8],["cis'",1/8],["h",1/4],["a",1/8],["g",1/8],["a",1/8],
      ["g",1/8],["fis",1/8],["g",1/8],["a",1/8],["h",1/8],["cis'",1/8],["d'",1/8],
      ["h",1/4],["d'",1/8],["cis'",1/8],["d'",1/4],
      ["cis'",1/8],["h",1/8],["cis'",1/8],["d'",1/8],["e'",1/8],["d'",1/8],["cis'",1/8],["d'",1/8],["h",1/8],["cis'",1/8],
  ["d'",1/2],[-1,1/2],["cis'",1/2],[-1,1/2],["h",1/2],[-1,1/2],["d'",1/2],[-1,1/2],
  ["d",1/2],[-1,1/2],["d",1/2],[-1,1/2],["d",1/2],[-1,1/2],["e",1/2],[-1,1/2],
  [-1,1/2],["a",1/2],[-1,1/2],["a",1/2],[-1,1/2],["fis",1/2],[-1,1/2],["a",1/2],
  [-1,1/2],["g",1/2],[-1,1/2],["fis",1/2],[-1,1/2],["g",1/2],[-1,1/2],["e'",1/2],
  ["fis'",1/4],["fis",1/4],["g",1/4],["fis",1/4],["e",1/4],["e'",1/4],["fis'",1/4],["e'",1/4],
      ["d'",1/4],["fis",1/4],["d",1/4],["h",1/4],["a",1/4],["A",1/4],["G",1/4],["A",1/4],
      ["H",1/4],["h",1/4],["cis'",1/4],["h",1/4],["a",1/4],["A",1/4],["G",1/4],["A",1/4],
      ["H",1/4],["h",1/4],["a",1/4],["h",1/4],["cis'",1/4],["cis",1/4],["H",1/4],["cis",1/4],
  ["d",1/4],["d'",1/4],["e'",1/4],["d'",1/4],["cis'",1/4],["cis",1/4],["d",1/4],["cis",1/4],
      ["H",1/4],["h",1/4],["a",1/4],["h",1/4],["cis'",1/4],["cis",1/4],["fis",1/4],["e",1/4],
      ["d",1/4],["d'",1/4],["e'",1/4],["g'",1/4],["fis'",1/4],["fis",1/4],["a",1/4],["fis'",1/4],
      ["d'",1/4],["g'",1/4],["fis'",1/4],["g'",1/4],["e'",1/4],["a",1/4],["g",1/4],["a",1/4],
  ["fis",1/4],["a",1/4],["a",1/4],["a",1/4],["a",1/4],["a",1/4],["a",1/4],["a",1/4],
      ["fis",1/4],["fis",1/4],["fis",1/4],["fis",1/4],["fis",1/4],["fis",1/4],["a",1/4],["a",1/4],
      ["g",1/4],["g",1/4],["g",1/4],["d'",1/4],["d'",1/4],["d'",1/4],["d'",1/4],["d'",1/4],
      ["d'",1/4],["d'",1/4],["h",1/4],["h",1/4],["a",1/4],["a",1/4],["e'",1/4],["cis'",1/4],
  ["a",1/4],["fis'",1/4],["fis'",1/4],["fis'",1/4],["e'",1/4],["e'",1/4],["e'",1/4],["e'",1/4],
      ["d'",1/4],["d'",1/4],["d'",1/4],["d'",1/4],["a'",1/4],["a'",1/4],["a'",1/4],["a'",1/4],
      ["h'",1/4],["h'",1/4],["h'",1/4],["h'",1/4],["a'",1/4],["a'",1/4],["a'",1/4],["a'",1/4],
      ["h'",1/4],["h'",1/4],["h'",1/4],["h'",1/4],["cis''",1/4],["cis'",1/4],["cis'",1/4],["cis'",1/4],
  ["d'",1/4],["d",1/8],["e",1/8],["fis",1/4],["d",1/4],["cis",1/4],["cis'",1/8],["d'",1/8],["e'",1/4],["d'",1/4],
      ["h",1/4],["H",1/8],["cis",1/8],["d",1/4],["H",1/4],["cis",1/4],["a",1/8],["g",1/8],["fis",1/4],["e",1/4],
      ["d",1/4],["g",1/8],["fis",1/8],["e",1/4],["g",1/4],["fis",1/4],["d",1/8],["e",1/8],["fis",1/4],["a",1/4],
      ["g",1/4],["h",1/8],["a",1/8],["g",1/4],["fis",1/4],["e",1/4],["a",1/8],["g",1/8],["fis",1/4],["e",1/4],
  ["fis",1/4],["d'",1/8],["cis'",1/8],["d'",1/4],["fis",1/4],["a",1/4],["a",1/8],["h",1/8],["cis'",1/4],["a",1/4],
      ["fis",1/4],["d'",1/8],["e'",1/8],["fis'",1/4],["d'",1/4],["fis'",1/4],["fis'",1/8],["e'",1/8],["d'",1/4],["cis'",1/4],
      ["h",1/4],["h",1/8],["a",1/8],["h",1/4],["cis'",1/4],["d'",1/4],["fis'",1/8],["e'",1/8],["d'",1/4],["fis'",1/4],
      ["g'",1/4],["d'",1/8],["cis'",1/8],["h",1/4],["h",1/4],["a",1/4],["e",1/4],["a",1/4],["a",1/4],
  ["a",3/2],["a",1/2],["d",3/2],["a",1/2],["g",1],["a",1],["g",1/2],["d",1/2],["d",3/4],["cis",1/4],
  ["d",1/2],["d'",1/2],["cis'",1],["h",1],["a",1],["d",3/4],["e",1/4],["fis",1],["h",1],["e",3/4],["e",1/4],
  ["fis",3/4],["fis'",1/4],["fis'",1/4],["g'",1/4],["fis'",1/4],["e'",1/4],
      ["d'",3/4],["d'",1/4],["d'",1/4],["e'",1/4],["d'",1/4],["cis'",1/4],
      ["h",1],["d'",1],["d'",1/4],["c'",1/4],["h",1/4],["c'",1/4],["a",3/4],["a",1/4],
  ["a",3/4],["a'",1/4],["a'",1/4],["h'",1/4],["a'",1/4],["g'",1/4],
      ["fis'",3/4],["fis'",1/4],["fis'",1/4],["g'",1/4],["fis'",1/4],["e'",1/4],
      ["d'",1/4],["c'",1/4],["h",1/4],["c'",1/4],["a",3/4],["a",1/4],["g",1/2],["d'",1/2],["cis'",3/4],["cis'",1/4],
  ["d'",1/2],["d'",1],["cis'",1],["h",1],["a",1],["g",1],["fis",1+1/4],["e",1/4],["e",1],
  ["fis",1/2],["fis'",1],["e'",1/2],["d'",1/2],["d''",1],["c''",1/2],
      ["h'",1],["d''",1/2],["a'",1/2],["h'",1],["a'",1],
  ["a'",1],["a",3/4],["g",1/4],["fis",1],["fis'",3/4],["e'",1/4],
      ["d'",3/2],["d'",1/2],["d'",1],["cis'",1],
  ["d'",1/2],["d",1/2],["cis",1/2],["cis'",1/2],["h",1/2],["H",1/2],["A",1/2],["a",1/2],
      ["g",1/2],["g'",1/2],["fis'",1/2],["fis",1/2],["e",1/2],["h",1/2],["e",1/2],["e'",1/2],
  ["fis'",1/2],["fis",1/2],["e",1/2],["e'",1/2],["d'",1/2],["d",1/2],["cis",1/2],["cis'",1/2],
      ["h",1/2],["h'",1/2],["a'",1/2],["a",1/2],["g",3/4],["e'",1/4],["a",1/2],["a",1/2]

];

bass = flatten(apply(1..28,([["D",1],["A'",1],["H'",1],["Fis'",1],["G'",1],["D'",1],["G'",1],["A'",1]])),levels->1)++[["D",2]];

tune = [["channel",0]]++bass++[["channel",1],["goto",8]]++melody++[["channel",2],["goto",16]]++melody++[["channel",3],["goto",24]]++melody;

instrument(33, channel->0); // Acoustic Bass
instrument(1, channel->1); // Acoustic Grand Piano
instrument(25, channel->2); // Acoustic Guitar (nylon)
instrument(12, channel->3); // Vibraphone

notes = [
  [-1],
  ["C", "Cis"],
  ["D"],
  ["E"],
  ["Fis"],
  ["G"],
  ["A"],
  ["H"],
  ["c", "cis"],
  ["d"],
  ["e"],
  ["fis"],
  ["g"],
  ["a"],
  ["h"],
  ["c'", "cis'"],
  ["d'"],
  ["e'"],
  ["fis'"],
  ["g'"],
  ["a'"],
  ["h'"],
  ["c''", "cis''"],
  ["d''"]
];

x = 0;
score = apply(melody, note,
  y = select(1..length(notes), i, contains(notes_i, note_1));
  if (length(y) != 1, err(note));
  res = [x, y_1, note_2];
  x = x + note_2;
  res
);

xscale = 2;
barlen = 0.5;
drawit() := (
  gsave();
  translate((0, -3));
  forall(1..5, draw((-100, #), (100, #), color->[0,0,0]));
  forall(-1..1, draw((8*xscale*#, -2), (8*xscale*#, 8), color->[0,0,1]));
  now = if(played, midiposition(), 0);
  translate((xscale*(16 - now), 0));
  forall(score, note,
    if (note_2 > 1,
      x = xscale*note_1;
      y = note_2/2 - 4.5;
      if (y <= 0, forall(ceil(y)..0, draw((x - barlen, #), (x + barlen, #), color->[0,0,0])));
      if (y >= 6, forall(6..floor(y), draw((x - barlen, #), (x + barlen, #), color->[0,0,0])));
    );
  );
  forall(score, note,
    if (note_2 > 1,
      off = (now - note_1) / 8;
      size = max(3, if (off < 1, 0, 10 - 10 * (off - floor(off))));
      x = xscale*note_1;
      y = note_2/2 - 4.5;
      draw((x, y), size->size);
    );
  );
  grestore();
);

sandclock() := (
  gsave(); translate((4*xscale, 0)); scale(1.25);
  fillpoly([(1,1),(1,2),(-1,2),(-1,1),(1,-1),(1,-2),(-1,-2),(-1,-1)],color->[1,1,1]);
  drawpoly([(1,1),(1,2),(-1,2),(-1,1),(1,-1),(1,-2),(-1,-2),(-1,-1)],size->20,color->[1,1,1]);
  fillpoly([(1,1),(1,1.5),(0,1),(-1,1.5),(-1,1),(0,0)],color->[1,0.8,0]);
  fillpoly([(1,-2),(1,-1.5),(0,-1),(-1,-1.5),(-1,-2)],color->[1,0.8,0]);
  drawpoly([(1,1),(1,2),(-1,2),(-1,1),(1,-1),(1,-2),(-1,-2),(-1,-1)],color->[0.3,0.2,0]);
  grestore();
);

</script>
<script id="cstick" type="text/x-cindyscript">
</script>
<script id="csdraw" type="text/x-cindyscript">

drawit();

if (loadinstruments([33, 1, 25, 12]),
  if (!played,
    played = true;
    playanimation();
    playmelody(tune,speed->75,channel->2)),
  sandclock();
)

</script>
<script type="text/javascript">

var cdy = CindyJS({
  ports: [{
    id: "CSCanvas", width: 800, height: 200,
    transform: [{visibleRect: [-18,5,25,-5]}]
  }],
  scripts: "cs*"
});

</script>
</head>

<body>
  <div id="CSCanvas"></div>
</body>

</html>
